#include "CompressFileWriterImp.h"
#include <stdlib.h>

CompressFileWriterImp::CompressFileWriterImp(void)
{
	_buffer = 0;
	_usedBits = 0;
	_writeCount = 0;
}

CompressFileWriterImp::~CompressFileWriterImp(void)
{
}

bool CompressFileWriterImp::OpenOutputFile(std::string file)
{
	_file.open(file.c_str(), std::ios::out | std::ios::binary);
	return true;
}

void CompressFileWriterImp::CloseFile()
{
	if(_usedBits > 0)
	{
		BYTE data = (BYTE)(_buffer << (8-_usedBits));
		_file.write(&data, sizeof(BYTE));
		_usedBits = 0;
		_buffer = 0;
		++_writeCount;
	}
	_file.close();
}

void CompressFileWriterImp::WriteString(std::string srcFilename)
{
	_file << srcFilename;
	_writeCount += srcFilename.size();
	char end = 0;
	_file.write(&end, 1);
	++_writeCount;
}

void CompressFileWriterImp::WriteDict(int bitSize, int code, int dataSize, BYTE* data)
{
	_file.write((char*)(&bitSize), sizeof(bitSize));
	_file.write((char*)(&code), sizeof(code));
	_file.write((char*)(&dataSize), sizeof(dataSize));
	_file.write(data, dataSize);
	_writeCount += (sizeof(int)*3 + dataSize);
}

void CompressFileWriterImp::WriteInt(int count)
{
	_file.write((char*)(&count), sizeof(count));
	_writeCount += (sizeof(int));
}

void CompressFileWriterImp::WriteData(int inputCode, int bitSize)
{
	if(_usedBits < 8)
	{
		_buffer = (_buffer << bitSize) + inputCode;
		_usedBits += bitSize;
	}

	while(_usedBits >= 8)
	{
		BYTE data = (BYTE)(_buffer >> (_usedBits-8));
		_file.write(&data, sizeof(BYTE));
		_usedBits -= 8;
		unsigned int flag = (1 << _usedBits) - 1;
		_buffer = _buffer & flag;
		++_writeCount;
	}
}

int CompressFileWriterImp::GetWriteBytes()
{
	return _writeCount;
}
